package camid.distribution.activeobject;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ObjectScheduler {

	public static enum ObjectSchedulerType {
		STATELESS,
		STATEFUL
	}
	
	private String objectId;
	
	private Object entity;
	
	private Lock lock;
	
	private final ObjectSchedulerType type;
	
//	private ExecutorService executor;

	public ObjectScheduler(String objectId, Object entity)
	{
		this(objectId, entity, ObjectSchedulerType.STATEFUL);
	}
	
	public ObjectScheduler(String objectId, Object entity,
			ObjectSchedulerType type) 
	{
		this.type = type;
		
		if(type.equals(ObjectSchedulerType.STATEFUL))
		{
			this.lock = new ReentrantLock();
		}
//		else
//		{
//			executor = Executors.newCachedThreadPool();
//		}
		
		this.objectId = objectId;
		this.entity = entity;
	}
	
	public void acquire()
	{
		if(type.equals(ObjectSchedulerType.STATEFUL))
		{
			this.lock.lock();
		}
	}
	
	public void release()
	{
		if(type.equals(ObjectSchedulerType.STATEFUL))
		{
			this.lock.unlock();
		}
	}

	public synchronized Object submitTask(String method, Object[] parameters) {
		
//		Future<Object> futureTask = null;
		ObjectTask task = new ObjectTask(entity, method, parameters);
		Object response = null;
//		try 
//		{
//			if(type.equals(ObjectSchedulerType.STATEFUL))
//			{
//				readLock.lock();
//			}
//			futureTask = executor.submit(task);
//		if(type.equals(ObjectSchedulerType.STATEFUL))
//		{
			response = task.call();
//		}
//		else
//		{
//			Future<?> future = executor.submit(task);
//			try {
//				response = future.get();
//			} catch (InterruptedException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			} catch (ExecutionException e) {
//				Throwable cause = e.getCause();
//				if(cause instanceof ApplicationException)
//				{
//					throw (ApplicationException) cause;
//				}
//			}
//		}
		
//		}
//		finally
//		{
//			if(type.equals(ObjectSchedulerType.STATEFUL))
//			{
//				readLock.unlock();
//			}
//		}
		return response;
	}
	
	
	public String getObjectId()
	{
		return this.objectId;
	}

	public Class<?> getEntityClass() 
	{	
		return entity.getClass();
	}
	
	public void setEntity(Object entity)
	{
		try 
		{
//			writeLock.lock();
			this.entity = entity;
		}
		finally
		{
//			writeLock.unlock();
		}
	}

	public Object getEntity() 
	{
		Object entity = null;
//		try
//		{
//			readLock.lock();
			entity = this.entity;
//		}
//		finally
//		{
//			readLock.unlock();
//		}
		return entity;
	}

}
